/*
 * PosterDialog.java
 * Graphic Dialog for finding movie posters from internet database

 *  This file is part of Spidex.
 *  
 *  Spidex is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  Spidex is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with Spidex.  If not, see <http://www.gnu.org/licenses/>.
 */

package spidex.posterSearcher;
import WindowLogger.WindowLoggerHandler;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker.StateValue;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import spidex.DVDInfo;
import spidex.FilmInfo;
import spidex.FilmInfoInterface;
import spidex.GUI;

/**
 * Dialog window purpose for finding film based on name from CSFD
 * @author  xatrix
 */
public class PosterDialog extends javax.swing.JDialog {
    
    /** Creates new form NewJDialog */
    public PosterDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        this.info = new FilmInfo();
        try {
            searcher = new CSFDPosterSearcher();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        this.iconLabel.setIcon ( new 
            ImageIcon(
                getClass().getResource("/spidex/resources/not_avail.jpg")
            )
        );

        this.iconLabel.setVisible(true);
        this.logger = Logger.getLogger("Spidex");
        logger.addHandler( WindowLoggerHandler.getInstance() );
    }
    
   /**
     * Function only fill GUI with actual values stored in info and also 
     * creates SwingWorker for finding additional info about movie 
     */
    private void updateWindow() {
        if(worker != null && worker.getState().equals( StateValue.STARTED)) {
            return;
        }
        if(info == null) {
            return;
        }

        infoWorker = new CSFDPosterSearcherInfoWorker(searcher,info);                

        infoWorker.addPropertyChangeListener( 
            new PropertyChangeListener() {
                public void propertyChange(PropertyChangeEvent evt) {
                    if(infoWorker.getState().equals( StateValue.DONE)) {
                        System.out.println("Stopped");
                        nameField.setText( info.getTitle() );
                        genreField.setText( info.getGenre() );
                        yearField.setText( ""+info.getYearOfRelease() );
                        lengthField.setText( ""+info.getLength()+"min" );
                        directorField.setText(
                            info.getDirectors().toString()
                        );
                        actorField.setText( info.getActors().toString() );
                        iconLabel.setIcon( info.getPoster() );
                        cancelButton.setEnabled(false);
                    }
                    if(infoWorker.getState().equals( StateValue.STARTED)) {
                        System.out.println("Starting");
                    }
                }
            }
        );
            
        this.cancelButton.setEnabled(true);
        infoWorker.execute();
    }
    
    /**
     * Function only set dvdInfo, enable posterButtons and update Window
     * @param dvdInfo contain actual DVDInfo which data would be stored
     */
    public void setInfo(DVDInfo dvdInfo) {
        if(dvdInfo != null) {
            this.dvdInfo = dvdInfo;
            if(dvdInfo.getFilmInfo() != null) {
                this.info = dvdInfo.getFilmInfo();
                if(info.getTitle() != null) {
                    this.searchField.setText( info.getTitle() );
                }
            }

            this.nextButton.setEnabled(true);
            this.prevButton.setEnabled(true);
            this.updateWindow();
        }
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        iconLabel = new javax.swing.JLabel();
        separator = new javax.swing.JSeparator();
        searchField = new java.awt.TextField();
        panel = new java.awt.Panel();
        nameField = new javax.swing.JTextField();
        nameLabel = new javax.swing.JTextField();
        directorLabel = new javax.swing.JTextField();
        actorLabel = new javax.swing.JTextField();
        directorField = new javax.swing.JTextField();
        actorField = new javax.swing.JTextField();
        genreLabel = new javax.swing.JTextField();
        genreField = new javax.swing.JTextField();
        yearLabel = new javax.swing.JTextField();
        yearField = new javax.swing.JTextField();
        lengthLabel = new javax.swing.JTextField();
        lengthField = new javax.swing.JTextField();
        jScrollPane1 = new javax.swing.JScrollPane();
        resultTree = new javax.swing.JTree();
        saveButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();
        nextButton = new javax.swing.JButton();
        prevButton = new javax.swing.JButton();
        findButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("spidex/posterSearcher/properties"); // NOI18N
        setTitle(bundle.getString("posterSearch")); // NOI18N

        iconLabel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        searchField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                searchFieldKeyPressed(evt);
            }
        });

        nameField.setEnabled(false);

        nameLabel.setEditable(false);
        nameLabel.setText(bundle.getString("name")); // NOI18N
        nameLabel.setBorder(null);
        nameLabel.setDisabledTextColor(new java.awt.Color(255, 255, 255));
        nameLabel.setSelectionColor(new java.awt.Color(255, 255, 255));

        directorLabel.setEditable(false);
        directorLabel.setText(bundle.getString("directed")); // NOI18N
        directorLabel.setBorder(null);

        actorLabel.setEditable(false);
        actorLabel.setText(bundle.getString("cast")); // NOI18N
        actorLabel.setBorder(null);

        directorField.setEnabled(false);

        actorField.setEnabled(false);

        genreLabel.setEditable(false);
        genreLabel.setText(bundle.getString("genre")); // NOI18N
        genreLabel.setBorder(null);

        genreField.setEnabled(false);

        yearLabel.setEditable(false);
        yearLabel.setText(bundle.getString("year")); // NOI18N
        yearLabel.setBorder(null);

        yearField.setEnabled(false);

        lengthLabel.setEditable(false);
        lengthLabel.setText(bundle.getString("length")); // NOI18N
        lengthLabel.setBorder(null);

        lengthField.setEnabled(false);

        resultTree.setModel(resultModel);
        resultTree.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                resultTreeMouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(resultTree);

        javax.swing.GroupLayout panelLayout = new javax.swing.GroupLayout(panel);
        panel.setLayout(panelLayout);
        panelLayout.setHorizontalGroup(
            panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(nameLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 85, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lengthLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE)
                    .addComponent(yearLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE)
                    .addComponent(genreLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE)
                    .addComponent(actorLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE)
                    .addComponent(directorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER, false)
                    .addComponent(nameField, javax.swing.GroupLayout.PREFERRED_SIZE, 175, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(directorField, javax.swing.GroupLayout.PREFERRED_SIZE, 175, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(actorField, javax.swing.GroupLayout.PREFERRED_SIZE, 175, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(genreField, javax.swing.GroupLayout.PREFERRED_SIZE, 175, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(yearField, javax.swing.GroupLayout.PREFERRED_SIZE, 175, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lengthField, javax.swing.GroupLayout.PREFERRED_SIZE, 175, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 182, Short.MAX_VALUE))
        );

        panelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {actorLabel, directorLabel, genreLabel, lengthLabel, nameLabel, yearLabel});

        panelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {actorField, directorField, genreField, lengthField, nameField, yearField});

        panelLayout.setVerticalGroup(
            panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 194, Short.MAX_VALUE)
                    .addComponent(nameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(panelLayout.createSequentialGroup()
                        .addComponent(nameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(directorField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(directorLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(actorField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(actorLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(genreField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(genreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(yearField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(yearLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(lengthLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lengthField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addContainerGap())
        );

        panelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {actorLabel, directorLabel, genreLabel, lengthLabel, nameLabel, yearLabel});

        panelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {actorField, directorField, genreField, lengthField, nameField, yearField});

        saveButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/spidex/resources/saveButton.png"))); // NOI18N
        saveButton.setText(bundle.getString("saveButton")); // NOI18N
        saveButton.setToolTipText(bundle.getString("saveButtonHint")); // NOI18N
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });

        cancelButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/spidex/resources/cancelButton.png"))); // NOI18N
        cancelButton.setToolTipText(bundle.getString("cancelButtonHint")); // NOI18N
        cancelButton.setEnabled(false);
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        nextButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/spidex/resources/nextButton.png"))); // NOI18N
        nextButton.setMaximumSize(new java.awt.Dimension(80, 24));
        nextButton.setMinimumSize(new java.awt.Dimension(80, 24));
        nextButton.setPreferredSize(new java.awt.Dimension(80, 24));
        nextButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nextButtonActionPerformed(evt);
            }
        });

        prevButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/spidex/resources/prevButton.png"))); // NOI18N
        prevButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                prevButtonActionPerformed(evt);
            }
        });

        findButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/spidex/resources/findFilmButton.png"))); // NOI18N
        findButton.setText(bundle.getString("find")); // NOI18N
        findButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                findButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addComponent(iconLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(prevButton, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(nextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addComponent(separator, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 611, Short.MAX_VALUE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(72, 72, 72)
                .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(searchField, javax.swing.GroupLayout.DEFAULT_SIZE, 242, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(findButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(saveButton, javax.swing.GroupLayout.PREFERRED_SIZE, 62, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(67, 67, 67))
        );

        layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {nextButton, prevButton});

        layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {findButton, saveButton});

        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(iconLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 12, Short.MAX_VALUE)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(prevButton)
                            .addComponent(nextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(separator, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(searchField, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cancelButton)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(saveButton)
                        .addComponent(findButton)))
                .addContainerGap())
        );

        layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {nextButton, prevButton});

        pack();
    }// </editor-fold>//GEN-END:initComponents

/**
 * Function tries to find previous poster on CSFD, 
 * if poster doesn't exist, previous button is disabled
 * @param evt
 */
    private void prevButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevButtonActionPerformed
        ImageIcon icon = null;
        Matcher patternResult;
        Pattern urlPattern;
        String url;
        String baseUrl;
        Integer posterId;
        
        if(info == null || info.getPosterUrl() == null) {
            return;
        }
        
        url = info.getPosterUrl();
        urlPattern = Pattern.compile("(.*_)(\\d+)\\.jpg");
        patternResult = urlPattern.matcher(url);
        if(!patternResult.matches() ) {
            this.nextButton.setEnabled(false);
            return;
        }
        baseUrl = patternResult.group(1);
        posterId = Integer.valueOf( patternResult.group(2) );
        url = baseUrl + --posterId +".jpg";
        try {
            icon = new ImageIcon(new URL(url) );
        } catch (MalformedURLException ex) {
            System.out.println("Wrong URL passed");
        }
        
        if(icon == null || icon.getIconWidth() < 0) {
            prevButton.setEnabled(false);
            return;
        }
        nextButton.setEnabled(true);
        info.setPoster(icon);
        info.setPosterUrl(url);
        this.updateWindow();
}//GEN-LAST:event_prevButtonActionPerformed

/**
 * Function tries to find next poster on CSFD, 
 * if poster doesn't exist, next button is disabled
 * @param evt
 */
    private void nextButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextButtonActionPerformed
        ImageIcon icon = null;
        Matcher patternResult;
        Pattern urlPattern;
        String url;
        String baseUrl;
        Integer posterId;
                
        if(info == null || info.getPosterUrl() == null) {
            return;
        }
        
        url = info.getPosterUrl();
        urlPattern = Pattern.compile("(.*_)(\\d+)\\.jpg");
        patternResult = urlPattern.matcher(url);
        
        if(!patternResult.matches() ) {
            this.nextButton.setEnabled(false);
            return;
        }
        
        baseUrl = patternResult.group(1);
        posterId = Integer.valueOf( patternResult.group(2) );
        url = baseUrl + ++posterId +".jpg";
        try {
            icon = new ImageIcon(new URL(url) );
        } catch (MalformedURLException ex) {
            System.out.println("Wrong URL passed");
        }
        
        if(icon == null || icon.getIconWidth() < 0) {
            nextButton.setEnabled(false);
            return;
        }
        prevButton.setEnabled(true);
        info.setPoster(icon);
        info.setPosterUrl(url);
        this.updateWindow();
}//GEN-LAST:event_nextButtonActionPerformed
  
/**
 * Function exectute function for finding film
 * @param evt
 */   
    private void searchFieldKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_searchFieldKeyPressed
        if( KeyEvent.VK_ENTER == evt.getKeyCode() ) {
            this.findFilm();
        }    
}//GEN-LAST:event_searchFieldKeyPressed
    
/**
 * Function execute update in main window when saveButton is clicked
 * @param evt
 */
    private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
        this.info.setPoster( (ImageIcon) this.iconLabel.getIcon() );
        dvdInfo.setFilmInfo(info);
        ((GUI) this.getParent() ).updateGUIInformation(dvdInfo);
        this.setInfo( new DVDInfo() );
    }//GEN-LAST:event_saveButtonActionPerformed

/**
 * Function get selected movie from result and execute updating GUI window
 * @param evt
 */
    private void resultTreeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_resultTreeMouseClicked
        if(! worker.getState().equals( StateValue.DONE) ||
                this.result == null) {
            return;
        } 
        
        this.nextButton.setEnabled(true);
        this.prevButton.setEnabled(true);
        
        int[] selectedRows = this.resultTree.getSelectionRows();
        if(selectedRows == null) {
            System.out.println("SelectedRows is null");
        }
        for(int index : selectedRows) {
            if(index == 0) {
                return;
            }
            this.info = result.get(index-1);
            this.updateWindow();
        }
    }//GEN-LAST:event_resultTreeMouseClicked

/**
 * Function kills all running Swingworkers
 * @param evt actual event telling what happend
 */
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
    boolean canceled;
    if(worker.getState().equals( StateValue.STARTED ) ) {
        canceled = worker.cancel(true);
        if(!canceled) {
            this.logger.log(
                Level.SEVERE,"Thread resultWorker cancelling failed"
            );
        }
    }
    if(infoWorker.getState().equals( StateValue.STARTED ) ) {
        canceled = infoWorker.cancel(true);
        if(!canceled) {
            this.logger.log(Level.SEVERE,"Thread infoWorker cancelling failed");
        }
    }
}//GEN-LAST:event_cancelButtonActionPerformed


private void findButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_findButtonActionPerformed
    this.findFilm();
}//GEN-LAST:event_findButtonActionPerformed
 
/**
 * Function prepare swingWworker for finding results and execute worker
 */
private void findFilm() {
    this.resultTree.collapseRow(1);
    this.nextButton.setEnabled(true);
    this.prevButton.setEnabled(true);
    topNode.removeAllChildren();
    worker = new CSFDPosterSearcherResultWorker(
            searcher,topNode
    );                

    worker.addPropertyChangeListener( 
        new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                if(worker.getState().equals( StateValue.DONE)) {
                    System.out.println("Done");
                    resultTree.updateUI();
                    resultTree.expandRow(1);
                    try {
                        result = worker.get();
                        if(result == null || result.isEmpty()) {
                            JOptionPane.showMessageDialog(
                                null, java.util.ResourceBundle.getBundle(
                                            "spidex/posterSearcher/properties").
                                                getString("noResult")
                            );
                        }
                    }
                    catch(ExecutionException ex) {
                        System.out.println(ex.getMessage());
                    }
                    catch(InterruptedException ex) {
                        System.out.println(ex.getMessage());
                    }
                    cancelButton.setEnabled(false);
                }
                if(worker.getState().equals( StateValue.STARTED)) {
                    System.out.println("Starting");
                }
            }
        }
    );

    worker.setName( this.searchField.getText() );
    this.cancelButton.setEnabled(true);
    worker.execute();
}
/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            PosterDialog dialog = new PosterDialog(
                    new javax.swing.JFrame(), true
            );

            dialog.addWindowListener(new java.awt.event.WindowAdapter() {
                @Override
                public void windowClosing(java.awt.event.WindowEvent e) {
                    System.exit(0);
                }
            });
            dialog.setVisible(true);
        }
    });
}
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField actorField;
    private javax.swing.JTextField actorLabel;
    private javax.swing.JButton cancelButton;
    private javax.swing.JTextField directorField;
    private javax.swing.JTextField directorLabel;
    private javax.swing.JButton findButton;
    private javax.swing.JTextField genreField;
    private javax.swing.JTextField genreLabel;
    private javax.swing.JLabel iconLabel;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextField lengthField;
    private javax.swing.JTextField lengthLabel;
    private javax.swing.JTextField nameField;
    private javax.swing.JTextField nameLabel;
    private javax.swing.JButton nextButton;
    private java.awt.Panel panel;
    private javax.swing.JButton prevButton;
    private javax.swing.JTree resultTree;
    private javax.swing.JButton saveButton;
    private java.awt.TextField searchField;
    private javax.swing.JSeparator separator;
    private javax.swing.JTextField yearField;
    private javax.swing.JTextField yearLabel;
    // End of variables declaration//GEN-END:variables
    private PosterSearcher searcher = null;
    private int resultIndex = 0;
    private List<FilmInfoInterface> result = null;
    private FilmInfoInterface info;
    private Logger logger;
    private DefaultMutableTreeNode topNode = new DefaultMutableTreeNode("Result");
    private TreeModel resultModel = new DefaultTreeModel(topNode);
    private CSFDPosterSearcherResultWorker worker;
    private CSFDPosterSearcherInfoWorker infoWorker;
    private DVDInfo dvdInfo = new DVDInfo();
}
